<!DOCTYPE html>
<html lang="en">

<!-- Head tag -->
<head><meta name="generator" content="Hexo 3.9.0">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="baidu-site-verification" content="Xijgc2YO5y">
	<meta name="baidu-site-verification" content="Qj80ZohAkr">
	<meta name="google-site-verification" content="N-bPfRy2yUxAuOVKpn0Gm7BOygzI_faxwpAUQq0T8xw">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Leeves在 Github 上的个人博客">
    <meta name="keyword" content="Leeves">
    <meta name="theme-color" content="#600090">
    <meta name="msapplication-navbutton-color" content="#600090">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="#600090">
    <link rel="shortcut icon" href="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-person-128.png">
    <link rel="alternate" type="application/atom+xml" title="Leeves" href="/atom.xml">
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
    <link rel="stylesheet" href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.css">
    <title>
        
        Android demo:下载进度条闪光效果（自定义View）—(by LineChen)｜Leeves&#39;s blog
        
    </title>

    <link rel="canonical" href="https://leevsee.github.io/2016/10/03/Android-demo-下载进度条闪光效果（自定义View）—-by-LineChen/">

    <!-- Bootstrap Core CSS -->
    <link rel="stylesheet" href="/css/bootstrap.min.css">

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/css/blog-style.css">

    <!-- Pygments Github CSS -->
    <link rel="stylesheet" href="/css/syntax.css">
	<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>
</head>

<style>

    header.intro-header {
        background-image: url('http://cdn.pcbeta.attachment.inimc.com/data/attachment/forum/201205/15/232126llvvucjetunjn8g2.jpg')
    }
</style>
<!-- hack iOS CSS :active style -->
<body ontouchstart="" class="animated fadeIn">
<!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top " id="nav-top" data-ispost = "true" data-istags="false
" data-ishome = "false" >
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand animated pulse" href="/">
                <span class="brand-logo">
                    Leeves
                </span>
                's Blog
            </a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <!-- Known Issue, found by Hux:
            <nav>'s height woule be hold on by its content.
            so, when navbar scale out, the <nav> will cover tags.
            also mask any touch event of tags, unfortunately.
        -->
        <!-- /.navbar-collapse -->
        <div id="huxblog_navbar">
            <div class="navbar-collapse">
                <ul class="nav navbar-nav navbar-right">
                    <li>
                        <a href="/">Home</a>
                    </li>

                    
                        
                    
                        
                        <li>
                            <a href="/Others/">Others</a>
                        </li>
                        
                    

                </ul>
            </div>
        </div>
    </div>
    <!-- /.container -->
</nav>
<script>
    // Drop Bootstarp low-performance Navbar
    // Use customize navbar with high-quality material design animation
    // in high-perf jank-free CSS3 implementation
//    var $body   = document.body;
    var $toggle = document.querySelector('.navbar-toggle');
    var $navbar = document.querySelector('#huxblog_navbar');
    var $collapse = document.querySelector('.navbar-collapse');

    $toggle.addEventListener('click', handleMagic)
    function handleMagic(e){
        if ($navbar.className.indexOf('in') > 0) {
        // CLOSE
            $navbar.className = " ";
            // wait until animation end.
            setTimeout(function(){
                // prevent frequently toggle
                if($navbar.className.indexOf('in') < 0) {
                    $collapse.style.height = "0px"
                }
            },400)
        }else{
        // OPEN
            $collapse.style.height = "auto"
            $navbar.className += " in";
        }
    }
</script>

<!-- Main Content -->

<!--only post-->


<img class="wechat-title-img"
     src="http://lixin.piaozu.com.cn/postPicture.jpg">


<style>
    
    header.intro-header {
        background-image: url('http://lixin.piaozu.com.cn/postPicture.jpg')
    }

    
</style>

<header class="intro-header">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 text-center">
                <div class="post-heading">
                    <h1>Android demo:下载进度条闪光效果（自定义View）—(by LineChen)</h1>
                    
                    <span class="meta">
                         作者 Leeves
                        <span>
                          日期 2016-10-03
                         </span>
                    </span>
                    <div class="tags text-center">
                        
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="post-title-haojen">
        <span>
            Android demo:下载进度条闪光效果（自定义View）—(by LineChen)
        </span>
    </div>
</header>

<!-- Post Content -->
<article>
    <div class="container">
        <div class="row">
            <!-- Post Container -->
            <div class="col-lg-8 col-lg-offset-1 col-sm-9 post-container">
                <p>十一感冒了，好伤啊。<br>这是带来的是Android 仿应用宝下载进度条（<a href="https://github.com/LineChen/FlickerProgressBar/blob/master/README.md" target="_blank" rel="noopener">by LineChen</a>）。</p>
<p><img src="https://github.com/LineChen/FlikerProgressBar/raw/master/screenshot/screenshot.gif" alt="此处输入图片的描述"></p>
<p><br>好啦，现在头晕，我在代码里面写的很详细了，就不多说了：<br></p>
<pre><code>public class DownBarView extends View implements Runnable{
    //SRC_ATOP :在源图像和目标图像相交的地方绘制源图像，在不相交的地方绘制目标图像：取下层绘制非交集部分。
    private PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP);

    private float MAX_PROGRESS = 100f;

    private Paint mBgPaint;

    private Paint mTextPaint;

    /**
     * 文字矩形
     */
    private Rect mTextBouds;

    private Canvas mPgCanvas;

    private int mTextSize;

    /**
     * 初始下载中颜色
     */
    private int mLoadingColor;

    /**
     * 暂停颜色
     */
    private int mStopColor;

    /**
     * 进度中变换颜色
     */
    private int mProgressColor;

    /**
     * 闪光Bitmap
     */
    private Bitmap mFlikerBitmap;

    /**
     * 背景Bitmap
     */
    private Bitmap mPgBitmap;

    private float mFlikerLeft;

    private Thread mThread;


    /**
     * 当前进度条
     */
    private float progress;

    private boolean isStop;

    private boolean isFinish;

    private String mProgressText;

    public DownBarView(Context context) {
        this(context, null, 0);
    }

    public DownBarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DownBarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs);
    }

    /**
     * 设置arrs.xml的值
     *
     * @param attrs
     */
    private void initAttrs(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DownBarView);
            mTextSize = (int) ta.getDimension(R.styleable.DownBarView_textSize, 12);
            mLoadingColor = ta.getColor(R.styleable.DownBarView_loadingColor, Color.parseColor(&quot;#40c4ff&quot;));
            mStopColor = ta.getColor(R.styleable.DownBarView_stopColor, Color.parseColor(&quot;#ff9800&quot;));
            ta.recycle();//回收TypedArray
        }
    }

    /**
     * 初始化
     */
    private void inti() {
        //用于绘制时抗锯齿
        mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //设置字体大小
        mTextPaint.setTextSize(mTextSize);
        mTextBouds = new Rect();
        mProgressColor = mLoadingColor;
        //获得发光图片及宽度
        mFlikerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flicker);
        mFlikerLeft = -mFlikerBitmap.getWidth();
        //获取view的宽，高度
        mPgBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        mPgCanvas = new Canvas(mPgBitmap);
        mThread = new Thread(this);
        mThread.start();
        Log.d(&quot;mFlikerLeft========================&quot;, &quot;inti: &quot; + mFlikerLeft);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 父容器传过来的高度方向上的模式
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        // 父容器传过来的高度的值
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        // 父容器传过来的宽度的值
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int height = 0;
        switch (heightSpecMode) {
            //最大模式：就是父组件，能够给出的最大的空间，当前组件的长或宽最大只能为这么大，当然也可以比这个小。
            case MeasureSpec.AT_MOST:
                height = (int) dp2px(35);
                break;
            //精确模式：在这种模式下，尺寸的值是多少，那么这个组件的长或宽就是多少。
            case MeasureSpec.EXACTLY:
            //未指定：当前组件，可以随便用空间，不受限制
            case MeasureSpec.UNSPECIFIED:
                height = heightSpecSize;
                break;
        }
        setMeasuredDimension(widthSpecSize, height);
        inti();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //进度条边框
        drawBorder(canvas);

        //进度条
        drawProgress();

        //背景图片
        canvas.drawBitmap(mPgBitmap, 0, 0, null);

        //进度条中的文字
        drawProgressText(canvas);

        //进度条文字变色处理
        drawColorProgressText(canvas);
    }

    /**
     * 绘制进度条的边框
     *
     * @param canvas
     */
    private void drawBorder(Canvas canvas) {
        //设置画出的图形是空心的
        mBgPaint.setStyle(Paint.Style.STROKE);
        mBgPaint.setColor(mProgressColor);
        mBgPaint.setStrokeWidth(dp2px(1));
        //左上右下，left和top是矩形的左上角的坐标，right和bottom是矩形的右下角的坐标，而paint则是画笔对象。而不是矩形的上下左右宽度等错误理解。
        canvas.drawRect(0, 0, getWidth(), getHeight(), mBgPaint);

    }

    /**
     * 绘制进度条
     */
    private void drawProgress() {
        //设置画出的图形是实心
        mBgPaint.setStyle(Paint.Style.FILL);
        mBgPaint.setStrokeWidth(0);
        mBgPaint.setColor(mProgressColor);
        //标志位没有保存相关的位移信息，restore的时候不能恢复
        mPgCanvas.save(Canvas.CLIP_SAVE_FLAG);
        //获得进度条在矩形的位置
        float right = (progress / MAX_PROGRESS) * getMeasuredWidth();
        //在当前进度条的背景
        mPgCanvas.clipRect(0, 0, right, getMeasuredHeight());
        mPgCanvas.drawColor(mProgressColor);
        //读取把上一次save();的状态，能够不断刷新进度条
        mPgCanvas.restore();

        //如果不停止的话，一直绘制闪光图片
        if (!isStop) {
            mBgPaint.setXfermode(xfermode);
            mPgCanvas.drawBitmap(mFlikerBitmap, mFlikerLeft, 0, mBgPaint);
            //清除混合模式
            mBgPaint.setXfermode(null);
        }
    }

    /**
     * 进度条文本
     *
     * @param canvas
     */
    private void drawProgressText(Canvas canvas) {
        mTextPaint.setColor(mProgressColor);
        //获得不同状态的文字
        mProgressText = getProgressText();
        //调用了getTextBounds()方法来获取到整个文字框的宽度和高度，并返回在Rect mTextBouds中
        mTextPaint.getTextBounds(mProgressText, 0, mProgressText.length(), mTextBouds);
        int tWidth = mTextBouds.width();
        int tHeight = mTextBouds.height();
        //设置文字框在整个进度条的中间，x,y坐标
        float xCoordinate = (getMeasuredWidth() - tWidth) / 2;
        float yCoordinate = (getMeasuredHeight() + tHeight) / 2;
        canvas.drawText(mProgressText, xCoordinate, yCoordinate, mTextPaint);
    }

    /**
     * 文字的变色处理
     *
     * @param canvas
     */
    private void drawColorProgressText(Canvas canvas) {
        mTextPaint.setColor(Color.WHITE);
        int tWidth = mTextBouds.width();
        int tHeight = mTextBouds.height();
        float xCoordinate = (getMeasuredWidth() - tWidth) / 2;
        float yCoordinate = (getMeasuredHeight() + tHeight) / 2;
        float progressWidth = (progress / MAX_PROGRESS) * getMeasuredWidth();

        //判断进度条是否大于文字
        if (progressWidth &gt; xCoordinate) {
            canvas.save(Canvas.CLIP_SAVE_FLAG);
            float right = Math.min(progressWidth, xCoordinate + tWidth * 1.1f);
            canvas.clipRect(xCoordinate, 0, right, getMeasuredHeight());
            canvas.drawText(mProgressText, xCoordinate, yCoordinate, mTextPaint);
            canvas.restore();
        }
    }

    public void setProgress(float progress) {
        if (!isStop) {
            this.progress = progress;
            //请求重新onDraw()，但只会绘制调用者本身
            invalidate();
        }
    }

    /**
     * 是否停止
     * @param stop
     */
    public void setStop(boolean stop) {
        isStop = stop;
        if (isStop) {
            mProgressColor = mStopColor;
        } else {
            mProgressColor = mLoadingColor;
            mThread = new Thread(this);
            mThread.start();
        }
        invalidate();
    }

    /**
     * 切换状态 暂停/下载
     */
    public void toggle() {
        if (!isFinish) {
            if (isStop) {
                setStop(false);
            } else {
                setStop(true);
            }
        }
    }

    /**
     *
     */
    public void finishLoad() {
        isFinish = true;
        setStop(true);
    }

    /**
     * 判断是否完成
     */
    public boolean isFinish() {
        return isFinish;
    }

    /**
     * 判断是否停止
     */
    public boolean isStop(){
        return isStop;
    }

    @Override
    public void run() {
        int width = mFlikerBitmap.getWidth();
        while (!isStop) {
            //闪光图片每次刷新前进5dp
            mFlikerLeft += dp2px(5);
            float progressWidth = (progress / MAX_PROGRESS) * getMeasuredWidth();
            //一开始的时候，把闪光图片放在view的左边，负宽度
            if (mFlikerLeft &gt;= progressWidth) {
                mFlikerLeft = -width;
            }
            //因为run不在主线程，所以用postInvalidate();
            postInvalidate();
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    private String getProgressText() {
        String text = &quot;&quot;;
        if (!isFinish) {
            if (!isStop) {
                text = &quot;下载中&quot; + progress + &quot;%&quot;;
            } else {
                text = &quot;继续下载&quot;;
            }
        } else {
            text = &quot;下载完成&quot;;
        }
        return text;
    }


    //Paint中都是是px，所以要把dp转成px
    private float dp2px(int dp) {
        float density = getContext().getResources().getDisplayMetrics().density;
        return dp * density;
    }
}
</code></pre><p><br>下面是Activity：<br></p>
<pre><code>public class DownBarActivity extends Activity {

    DownBarView mDownBarView;
    Button mButton;
    private Handler mHandler = new DownLoadHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_down_bar);
        mDownBarView = (DownBarView) findViewById(R.id.downbar);
        mButton = (Button) findViewById(R.id.bn1);

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //异步操作
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        downLoad(&quot;http://imtt.dd.qq.com/16891/55D056A6FCC3E049B252DA1FE189677F.apk&quot;);
                    }
                }).start();
            }
        });
    }


    private void downLoad(String apkUrl) {
        try {
            URL url = new URL(apkUrl);
            URLConnection urlConnection = url.openConnection();
            InputStream inputStream = urlConnection.getInputStream();
            //故获得要下载文件的大小
            int contentLength = urlConnection.getContentLength(); 
            String downloadFoldersName = Environment.getExternalStorageDirectory() + File.separator + &quot;MyTestDemo&quot; + File.separator;

            File file = new File(downloadFoldersName);
            if (!file.exists()) {
                file.mkdir();
            }

            String fileName = downloadFoldersName + &quot;test.apk&quot;;
            File apkFile = new File(fileName);
            if (apkFile.exists()) {
                apkFile.delete();
            }

            int downloadSize = 0;
            byte[] bytes = new byte[1024];
            int length = 0;

            OutputStream outputStream = new FileOutputStream(fileName);
            //把进度值放入Message中
            while((length = inputStream.read(bytes)) != -1){
                outputStream.write(bytes,0,length);
                downloadSize += length;
                int progress = downloadSize * 100 / contentLength;
                Message message = mHandler.obtainMessage();
                message.what = 0;
                message.obj = progress;
                mHandler.sendMessage(message);
            }
            inputStream.close();
            outputStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
    * 通过Handler获取Message中进度条的进度，并设置进度值
    */
    public static class DownLoadHandler extends Handler{
        //弱引用
        public final WeakReference&lt;DownBarActivity&gt; mDownBarActivityWeakReference;

        public DownLoadHandler(DownBarActivity downBarActivityWeakReference) {
            mDownBarActivityWeakReference = new WeakReference&lt;&gt;(downBarActivityWeakReference);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            DownBarActivity downBarActivity = mDownBarActivityWeakReference.get();
            switch (msg.what){
                case 0:
                    int progress = (int) msg.obj;
                    downBarActivity.getDownBarView().setProgress(progress);
                    if (msg.arg1 == 100) {
                        downBarActivity.getDownBarView().finishLoad();
                    }
            }
        }
    }


    public DownBarView getDownBarView() {
        return mDownBarView;
    }
}
</code></pre><p>这样就可以实现基本效果了，但是还没有暂停再次下载的效果，下次demo弄。~~ (&gt;_&lt;) ~~感冒好难受了<br><br></p>
<p>PS：开发自定义View，通常可以被用户重写的方法如下：<br></p>
<blockquote>
<p><strong>构造器</strong>：重写构造器是定制View的最基本方式，当Java代码创建一个View事例，或根于XML布局文件加载并构建界面时将需要调用构造器。</p>
</blockquote>
<blockquote>
<p><strong>onFnishInflate()：</strong>这是一个回调方法，当应用从XML布局文件加载该组件并利用它来构建界面之后，该方法将会被回调。</p>
</blockquote>
<blockquote>
<p><strong>onMeasure(int,int)：</strong>调用该方法来检测View组件及它所包含的所有子组件的大小。</p>
</blockquote>
<blockquote>
<p><strong>onLayout(boolean,int,int,int,int)：</strong>当该组件需要分配其自组件的位置、大小时，该方法就会被回调。</p>
</blockquote>
<blockquote>
<p><strong>onSizeChanged(int,int,int,int)：</strong>当该组件的大小被改变时回调该方法。</p>
</blockquote>
<blockquote>
<p><strong>onDraw(Canvas)：</strong>当该组件需要绘制它的内容时回调该方法进行绘制。</p>
</blockquote>
<blockquote>
<p><strong>onKeyDown(int,KeyEvent)：</strong>当某个键被按下时触发该方法。</p>
</blockquote>
<blockquote>
<p><strong>onKeyUp(int,KeyEvent)：</strong>当松开某个按键时触发该方法。</p>
</blockquote>
<blockquote>
<p><strong>onTrackballEvent(MotionEvent)：</strong>当发生轨迹球事件时触发该方法</p>
</blockquote>
<blockquote>
<p><strong>onTouchEvent(MotionEvent)：</strong>当发生触摸屏事件时触发该方法</p>
</blockquote>
<blockquote>
<p><strong>onFocusChanged(boolean gainFocus,int direction,Rect previouslyFocusedRect):</strong>当该组件焦点发生改变时触发该方法</p>
</blockquote>
<blockquote>
<p><strong>onWindowFocusChanged(boolean)：</strong>当该组件得到、失去焦点时触发该方法。</p>
</blockquote>
<blockquote>
<p><strong>onAttachedToWindow()：</strong>当把组件放入某个窗口时触发该方法</p>
</blockquote>
<blockquote>
<p><strong>onDetachedFrowWindow()：</strong>当把组件从某个窗口上分离时触发该方法。</p>
</blockquote>
<blockquote>
<p><strong>onWindowVisibilityChanged(int)：</strong>当包含该组件的窗口的可见性发生改变时触发该方法。<br></p>
</blockquote>

                <hr>
                
                <!-- 多说 Share start -->
                <div class="ds-share"
                     style="text-align: right"
                     data-thread-key="2016/10/03/Android-demo-下载进度条闪光效果（自定义View）—-by-LineChen/"
                     data-title="Android demo:下载进度条闪光效果（自定义View）—(by LineChen)"
                     data-url="https://leevsee.github.io/2016/10/03/Android-demo-下载进度条闪光效果（自定义View）—-by-LineChen/"
                     data-images=""
                     data-content="十一感冒了，好伤啊。这是带来的是Android 仿应用宝下载进度条（by LineChen）。... | Leeves&#39;s blog ">
                    <div class="ds-share-inline">
                        <ul class="ds-share-icons-16">
                            <li data-toggle="ds-share-icons-more"><a class="ds-more" href="#">分享到：</a></li>
                            <li><a class="ds-wechat flat" href="javascript:void(0);" data-service="wechat">微信</a></li>
                            <li><a class="ds-weibo flat" href="javascript:void(0);" data-service="weibo">微博</a></li>
                            <li><a class="ds-douban flat" href="javascript:void(0);" data-service="douban">豆瓣</a></li>
                        </ul>
                        <div class="ds-share-icons-more">
                        </div>
                    </div>
                    <hr>
                </div>
                <!-- 多说 Share end-->
                

                <ul class="pager">
                    
                    <li class="previous">
                        <a href="/2016/10/10/Android-基础：View类的XML属性，相关方法/" data-toggle="tooltip" data-placement="top"
                           title="Android 基础：View类的XML属性，相关方法">&larr; Previous Post</a>
                    </li>
                    
                    
                    <li class="next">
                        <a href="/2016/09/28/Android-框架：AndroidAnnotations学习及问题/" data-toggle="tooltip" data-placement="top"
                           title="Android-框架：AndroidAnnotations学习及出现问题">Next Post &rarr;</a>
                    </li>
                    
                </ul>

                
                <!-- 多说评论框 start -->
                <div class="comment">
                    <div class="ds-thread"
                         data-thread-key="2016/10/03/Android-demo-下载进度条闪光效果（自定义View）—-by-LineChen/"
                         data-title="Android demo:下载进度条闪光效果（自定义View）—(by LineChen)"
                         data-url="https://leevsee.github.io/2016/10/03/Android-demo-下载进度条闪光效果（自定义View）—-by-LineChen/">
                    </div>
                </div>
                <!-- 多说评论框 end -->
                

                

            </div>

            <div class="hidden-xs col-sm-3 toc-col">
                <div class="toc-wrap">
                    
                </div>
            </div>
        </div>

        <div class="row">
            <!-- Sidebar Container -->

            <div class="
                col-lg-8 col-lg-offset-2
                col-md-10 col-md-offset-1
                sidebar-container">

                <!-- Featured Tags -->
                
                <section>
                    <!-- no hr -->
                    <h5 class="text-center">
                        <a href="/tags/">FEATURED TAGS</a>
                    </h5>
                    <div class="tags">
                        
                    </div>
                </section>
                

                <!-- Friends Blog -->
                
                <div style="margin-top: 20px;">
                    <h5 class="text-center">FRIENDS</h5>
                    <ul class="list-inline text-center">
                        
                        <li><a href="https://leevsee.github.io/#">lixin</a></li>
                        
                    </ul>
                </div>
                
            </div>
        </div>

    </div>
</article>


<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
<script type="text/javascript">
    // dynamic User by Hux
    var _user = 'leeves';

    // duoshuo comment query.
    var duoshuoQuery = {short_name: _user};
    (function () {
        var ds = document.createElement('script');
        ds.type = 'text/javascript';
        ds.async = true;
        ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
        ds.charset = 'UTF-8';
        (document.getElementsByTagName('head')[0]
        || document.getElementsByTagName('body')[0]).appendChild(ds);
    })();
</script>
<!-- 多说公共JS代码 end -->





<!-- Footer -->
<!-- Footer -->
<footer>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 text-center">
                <br>
                <ul class="list-inline text-center">
                
                
                    <li>
                        <a target="_blank" href="https://twitter.com/lxsweety">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                
                

                

                
                    <li>
                        <a target="_blank" href="https://www.facebook.com/lxsweety">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                

                
                    <li>
                        <a target="_blank"  href="https://github.com/Leevsee">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                

                

                </ul>
                <p class="copyright text-muted">
                    Copyright &copy; Leeves 2019
                    <br>
                    <span id="busuanzi_container_site_pv" style="font-size: 12px;">PV: <span id="busuanzi_value_site_pv"></span> Times</span>
                    <br>
                    Theme by <a href="http://kaijun.rocks/hexo-theme-huxblog/" style=" color:#666; font-size:8px;">Kaijun</a>
                </p>

            </div>
        </div>
    </div>
</footer>

<!-- jQuery -->
<script src="/js/jquery.min.js"></script>

<!-- Bootstrap Core JavaScript -->
<script src="/js/bootstrap.min.js"></script>

<!-- Custom Theme JavaScript -->
<script src="/js/blog.js"></script>

<!-- async load function -->
<script>
    function async(u, c) {
      var d = document, t = 'script',
          o = d.createElement(t),
          s = d.getElementsByTagName(t)[0];
      o.src = u;
      if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
      s.parentNode.insertBefore(o, s);
    }
</script>

<!-- jquery.tagcloud.js -->
<script>
    // only load tagcloud.js in tag.html
    if($('#tag_cloud').length !== 0){
        async("https://leevsee.github.io/js/jquery.tagcloud.js",function(){
            $.fn.tagcloud.defaults = {
                //size: {start: 1, end: 1, unit: 'em'},
                color: {start: '#bbbbee', end: '#0085a1'},
            };
            $('#tag_cloud a').tagcloud();
        })
    }
</script>

<!--fastClick.js -->
<script>
    async("//cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js", function(){
        var $nav = document.querySelector("nav");
        if($nav) FastClick.attach($nav);
    })
</script>

<!-- Google Analytics -->



<!-- Baidu Tongji -->


<!-- swiftype -->
<script type="text/javascript">
  (function(w,d,t,u,n,s,e){w['SwiftypeObject']=n;w[n]=w[n]||function(){
  (w[n].q=w[n].q||[]).push(arguments);};s=d.createElement(t);
  e=d.getElementsByTagName(t)[0];s.async=1;s.src=u;e.parentNode.insertBefore(s,e);
  })(window,document,'script','//s.swiftypecdn.com/install/v2/st.js','_st');

  _st('install','null','2.0.0');
</script>

<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>

<!--wechat title img-->
<img class="wechat-title-img" src="http://lixin.piaozu.com.cn/icon1.jpg">
</body>

</html>
